package com.lry.rpc.netty.server;

import com.lry.common.CommonConstants;
import com.lry.exception.FrameworkException;
import com.lry.protocol.RpcInvocation;
import com.lry.registy.URL;
import com.lry.rpc.config.RpcServiceBean;
import com.lry.rpc.netty.BeanKey;
import com.lry.util.CollectionUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class ServerCache {

    //<ServiceBeanKey,<group,RpcServiceBean>>
    private static Map<BeanKey,Map<String,RpcServiceBean>> SERVICE_BEAN_MAP = new ConcurrentHashMap<>();

    public static final Set<URL> PROVIDER_URL_SET = new HashSet<>();

    public static Set<BeanKey> getServiceBeanKeys(){
        return SERVICE_BEAN_MAP.keySet();
    }

    public static void registerService(RpcServiceBean rpcServiceBean){
        if(null==rpcServiceBean){
            throw new FrameworkException("rpcServiceBean is null");
        }

        String interfaceName = rpcServiceBean.getInterfaceName();
        String implName = rpcServiceBean.getServiceImplName();
        String version = rpcServiceBean.getVersion();
        BeanKey serviceBeanKey = new BeanKey(interfaceName,implName,version);

        SERVICE_BEAN_MAP.compute(serviceBeanKey,(k,v)->{
            if(null==v){
                v = new HashMap<>();
            }
            v.put(rpcServiceBean.getGroup(),rpcServiceBean);
            return v;
        });
    }

    public static Map<String,RpcServiceBean> getGroupServices(BeanKey serviceBeanKey){
        Map<String, RpcServiceBean> group2RpcServiceBean = SERVICE_BEAN_MAP.get(serviceBeanKey);
        if(CollectionUtils.isEmpty(group2RpcServiceBean)){
            throw new FrameworkException(String.format("RpcServiceBean is null,serviceBeanKey=%s",serviceBeanKey));
        }
        return group2RpcServiceBean;
    }

    public static RpcServiceBean getService(RpcInvocation rpcInvocation){
        String group = (String) rpcInvocation.getAttachments().get(CommonConstants.SPEC_GROUP_KEY);
        BeanKey beanKey = BeanKey.getBeanKey(rpcInvocation);
        RpcServiceBean rpcServiceBean = ServerCache.getService(beanKey,group);
        if(null==rpcServiceBean){
            throw new FrameworkException("rpcServiceBean is null");
        }
        return rpcServiceBean;
    }


    public static RpcServiceBean getService(BeanKey serviceBeanKey, String group){
        Map<String, RpcServiceBean> group2RpcServiceBean = SERVICE_BEAN_MAP.get(serviceBeanKey);
        if(CollectionUtils.isEmpty(group2RpcServiceBean)){
            throw new FrameworkException(String.format("RpcServiceBean is null,serviceBeanKey=%s",serviceBeanKey));
        }
        if(null==group){
            group = "";
        }
        RpcServiceBean rpcServiceBean = group2RpcServiceBean.get(group);
        if(null==rpcServiceBean){
            throw new FrameworkException(String.format("找不到服务,serviceBeanKey=%s",serviceBeanKey));
        }
        return rpcServiceBean;
    }

}
